package svgedit.gui.actions;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import svgedit.gui.ColorChooser;
import svgedit.gui.Frame;
import svgedit.gui.View;
import svgedit.svg.SVGElement;
import svgedit.svg.SVGGroup;
import svgedit.svg.SVGPaint;
import svgedit.svg.SVGStylableElement;

/**
 * This is a listener class that handles choosing colour actions
 * It handles when the colour is chosen or none,
 * as well as applying the colour to selected elements/groups
 * and parsing the new colour to the toolbar to display
 * @author SARJ
 * 
 */
public class ChooseColorAction implements ActionListener, ChangeListener
{

	private JButton colorPreviewBox;
	private int opt;
	private JColorChooser tcc;
	private ColorChooser dialog;

	/**
	 * Construct the action
	 * 
	 * @param btn
	 * @param opt
	 */
	public ChooseColorAction(JButton btn, int opt)
	{
		this.colorPreviewBox = btn;
		this.opt = opt;
		// this.f = Frame.getFrame();
	}

	/**
	 * Overload the constructor to handle the dialog, For changing colour on
	 * selected elements
	 * 
	 * @param btn
	 * @param tcc
	 * @param opt
	 */
	public ChooseColorAction(JButton btn, JColorChooser tcc, int opt)
	{
		this.colorPreviewBox = btn;
		this.tcc = tcc;
		this.opt = opt;

		// this.f = Frame.getFrame();
		// this.view = f.getView();
	}

	/**
	 * Overload the constructor to handle the dialog, For changing colour on
	 * selected elements
	 * 
	 * @param btn
	 * @param tcc
	 * @param opt
	 */
	public ChooseColorAction(JButton btn, JColorChooser tcc, int opt,
			ColorChooser colorChooser)
	{
		this.colorPreviewBox = btn;
		this.tcc = tcc;
		this.opt = opt;

		this.dialog = colorChooser;
		// this.view = f.getView();
	}

	/**
	 * Handle the action made when NONE colour is clicked
	 */
	@Override
	public void actionPerformed(ActionEvent arg0)
	{
		// If none is clicked
		if (arg0.getActionCommand() == "None")
		{
			// Change button on toolbar
			colorPreviewBox.setBackground(null);

			// Change appropriate button and set colours
			if (opt == ColorChooser.FILL_OPTION)
				Frame.getFrame().getToolbar().setFillColor(null);
			else if (opt == ColorChooser.STROKE_OPTION)
				Frame.getFrame().getToolbar().setStrokeColor(null);

			// Parse the new colour to elements
			colourSelection(null, this.opt);
			dialog.dispose();
		}
		else
		{
			// Show color dialog
			Frame f = Frame.getFrame();
			f.drawColorChooser(colorPreviewBox, this.opt);
		}

	}

	/**
	 * Triggered when a colour is clicked on the JColourChooser
	 */
	@Override
	public void stateChanged(ChangeEvent e)
	{
		// Parse colour to appropirate box
		colorPreviewBox.setBackground(this.tcc.getColor());
		colourSelection(this.tcc.getColor(), this.opt);
	}

	/**
	 * Parse the chosen colour to selected elements
	 * 
	 * @param c
	 *            The colour
	 * @param opt
	 *            The stroke or fill option
	 */
	private void colourSelection(Color c, int opt)
	{
		// Loop through all the elements
		View v = Frame.getFrame().getView();
		for (SVGElement e : (v.getSelected()))
		{

			// If an element
			if (e instanceof SVGStylableElement)
			{
				colourElement(c, e, opt, v);
			}
			// If a group colour all elements
			else if (e instanceof SVGGroup)
				colourGroup(c, (SVGGroup) e, opt, v);
		}
	}

	/**
	 * Colour an element using the parsed in colour
	 * 
	 * @param c
	 *            The colour
	 * @param e
	 *            THe element
	 * @param opt
	 *            The stroke/fill option
	 * @param v
	 *            The view
	 */
	private void colourElement(Color c, SVGElement e, int opt, View v)
	{

		// Is fill option?
		if (opt == ColorChooser.FILL_OPTION)
		{
			SVGPaint paint = ((SVGStylableElement) e).getFill();

			// If a COLOUR was chosen
			if (c != null)
			{
				// Paint element
				paint.setRGBColor(c);
			}
			else
			// If NONE was chosen
			{
				paint.setValueFromString("none");
			}
			((SVGStylableElement) e).setFill(paint);
		}
		// Stroke option was chosen
		else if (opt == ColorChooser.STROKE_OPTION)
		{
			// Paint the element
			SVGPaint paint = ((SVGStylableElement) e).getStroke();
			paint.setRGBColor(c);
			((SVGStylableElement) e).setStroke(paint);

		}
		v.repaint();
	}

	/**
	 * Colour a selected group with the new colour
	 * 
	 * @param c
	 *            The Colour
	 * @param g
	 *            The group
	 * @param opt
	 *            THe stroke/fill option
	 * @param v
	 *            The view reference
	 */
	private void colourGroup(Color c, SVGGroup g, int opt, View v)
	{
		// Loop through all elements in group
		for (SVGElement e : g)
		{

			// If its styleable colour the element
			if (e instanceof SVGStylableElement)
			{
				colourElement(c, e, opt, v);
			}
			// Otherwise colour the group - recursive!
			else if (e instanceof SVGGroup)
				colourGroup(c, (SVGGroup) e, opt, v);
		}
	}

}
